#ifdef SU1
#define _GLIBCXX_DEBUG
#endif

#include <algorithm>
#include <bitset>
#include <cassert>
#include <climits>
#include <cstring>
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cmath>
#include <fstream>
#include <iostream>
#include <iomanip>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <stack>
#include <set>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#define forn(i, n) for (int i = 0; i < int(n); i++)
#define forl(i, n) for (int i = 1; i <= int(n); i++)
#define ford(i, n) for (int i = int(n) - 1; i >= 0; i--)
#define fore(i, l, r) for (int i = int(l); i <= int(r); i++)
#define pb(a) push_back(a)
#define mp(x, y) make_pair((x), (y))
#define sz(a) (int) (a).size()
#define all(a) (a).begin(), (a).end()
#define ft first
#define sc second
#define x first
#define y second

template<typename X> inline X abs(const X& a) { return a < 0 ? -a : a; }
template<typename X> inline X sqr(const X& a) { return a * a; }

typedef long long li;
typedef long double ld;
typedef pair<int, int> pt;

const int INF = int(1e9);
const li INF64 = li(1e18);
const ld PI = acosl(ld(-1));
const ld EPS = 1e-9;

const int N = 100 + 3;
const int MAXT = 10 * 1000 + 3;

int n, m, T;
int p[N], t[N], k[N];
vector <int> g[N], tg[N];
int used[N], c[N], C;
bool hasLoop[N];
vector<int> comps[N];

inline bool read()
{
	if (scanf("%d%d%d", &n, &m, &T) != 3 || (n == 0 && m == 0 && T == 0)) return false;
	forn(i, n) assert(scanf("%d%d%d", &p[i], &t[i], &k[i]) == 3);
	forn(i, n)
	{
		comps[i].clear();
		hasLoop[i] = false;
		g[i].clear();
		tg[i].clear();
		used[i] = false;
		c[i] = -1;
	}
	C = 0;
	forn(i, m)
	{
		int a, b;
		assert(scanf("%d%d", &a, &b) == 2);
		--a, --b;
		g[a].pb(b);
		tg[b].pb(a);
		if (a == b) hasLoop[a] = true;
	}
	return true;
}

vector<int> perm;

void dfs (int v)
{
	used[v] = true;
	forn(i, sz(g[v]))
		if (!used[g[v][i]])
			dfs(g[v][i]);
	perm.pb(v);
}

void css (int v)
{
	comps[C].pb(v);
	c[v] = C;
	forn(i, sz(tg[v]))
		if (c[tg[v][i]] == -1)
			css(tg[v][i]);
}

template<typename T>
struct MaxStack {
	stack < pair<T, T> > q;
	void push(T val) {
		q.push(mp(max(getMax(), val), val));
	}
	void pop() {
		q.pop();
	}
	T getMax() {
		if (q.empty())
			return mp(-INF, -INF);
		return q.top().x;
	}
};

template <typename T>
struct MaxQueue {
	MaxStack<T> q1, q2;
	void push(T val) {
		q1.push(val);
	}
	void pop() {
		if (q2.q.empty()) {
			while (!q1.q.empty()) {
				q2.push(q1.q.top().y);
				q1.pop();
			}
		}
		q2.pop();
	}
	T getMax() {
		return max(q1.getMax(), q2.getMax());
	}
	bool empty()
	{
		return q1.q.empty() && q2.q.empty();
	}
	void clear()
	{
		while (!empty()) pop();
	}
};

MaxQueue<pt> q[MAXT];
int add[MAXT];
int z[MAXT];

inline void calc (int curComp, int d[MAXT])
{
	if (sz(comps[curComp]) == 1 && !hasLoop[comps[curComp][0]]) k[comps[curComp][0]] = 1;
	
	forn(idx, sz(comps[curComp]))
	{
		int v = comps[curComp][idx];
		forn(i, T + 1)
		{
			q[i].clear();
			add[i] = 0;
		}
		
		forn(w, T + 1)
		{
			z[w] = d[w];
			int numDeq = w % t[v];
			while (!q[numDeq].empty() && q[numDeq].getMax().sc + t[v] * k[v] < w) q[numDeq].pop();
			add[numDeq] += p[v];
			
			if (!q[numDeq].empty())
			{
				int val = q[numDeq].getMax().ft;
				z[w] = max(z[w], val + add[numDeq]);
			}
			
			q[numDeq].push(mp(d[w] - add[numDeq], w));
		}
		
		forn(i, T + 1) d[i] = z[i];
	}
}

int d[N][MAXT];
int used2[N], u2;

inline void solve()
{
	perm.clear();
	forn(i, n) if (!used[i]) dfs(i);
	reverse(all(perm));
	assert(sz(perm) == n);
	forn(i, n) if (c[perm[i]] == -1)
	{
		css(perm[i]);
		C++;
	}
	forn(i, C) used[i] = false;
	
	//forn(i, C) { forn(j, sz(comps[i])) cerr << comps[i][j] + 1 << ' '; cerr << endl; }
	
	forn(i, C) forn(j, T + 1) d[i][j] = 0;
	
	ford(i, sz(perm))
	{
		int curComp = c[perm[i]];
		if (used[curComp]) continue;
		used[curComp] = true;
		calc(curComp, d[curComp]);
		
		//forn(w, T + 1) cerr << d[curComp][w] << ' '; cerr << endl;
		
		u2++;		
		forn(j, sz(comps[curComp]))
		{
			int v = comps[curComp][j];
			forn(k, sz(tg[v]))
			{
				int toComp = c[tg[v][k]];
				if (toComp == curComp || used2[toComp] == u2) continue;
				used2[toComp] = u2;
				assert(!used[toComp]);
				forn(w, T + 1) d[toComp][w] = max(d[toComp][w], d[curComp][w]);
			}
		}
	}
	
	int ans = 0;
	forn(i, C) forn(j, T + 1) ans = max(ans, d[i][j]);
	printf("%d\n", ans);
}

int main()
{
#ifdef SU1
	assert(freopen("input.txt", "rt", stdin));
//	assert(freopen("output.txt", "wt", stdout));
#endif

	cout << fixed << setprecision(10);
	cerr << fixed << setprecision(5);

	while (read())
		solve();
	
#ifdef SU1
	cerr << "=== TIME : " << clock() << " ===" << endl;
#endif
	return 0;
}
